#!/usr/bin/env groovy
// @file     SigninProcessor
// @purpose  signin processor
// @author   Mac Radigan  

package ycoa.scan.signin

import org.codehaus.groovy.scriptom.*
import au.com.bytecode.opencsv.*
import java.text.*
import java.util.TimeZone

import ycoa.xml.*
import ycoa.service.*
import ycoa.session.*
import ycoa.markup.*
import ycoa.xml.*
import ycoa.scan.process.*
import ycoa.scan.signin.*
import ycoa.graphics.*
import ycoa.archive.*

public class TechVisionSigninProcessor extends SigninProcessor {

  private String message
  private AntBuilder ant = new AntBuilder()
  private String host
  private String port
  private String username
  private String password
  private String referenceFile
  private String logsBase
  private String inputRoot
  private String outputRoot
  private String outputFile
  private String market
  private String sourceRoot
  private String logsRoot
  private long epoch = System.currentTimeMillis()/1000

  TechVisionSigninProcessor() {
    configure("test")
  }

  TechVisionSigninProcessor(String market) {
    configure(market)
  }

  public void configure(market) {
    // CONFIGURATION SETTINGS
    def root = System.getenv("YCOA_WEB_HOME")
    def configuration = new ConfigSlurper().parse(new File("$root/ycoa.conf").toURL())
    //   host
    host = configuration.server.test.host
    port = configuration.server.test.port
    //   account
    username = configuration.modules.scan.account.username
    password = configuration.modules.scan.account.password
    //   forms
    referenceFile = configuration.modules.scan.forms.signin.reference
    logsBase = configuration.modules.scan.forms.signin.logs
    //   processing
    inputRoot = configuration.modules.scan.processing.datain
    outputRoot = configuration.modules.scan.processing.dataout
    //   intermediate file
    //outputFile = "${outputRoot}${File.separator}output.csv"
    outputFile = "${outputRoot}${File.separator}output.xml"
    // SELECT MARKET
    //market = "test"
    sourceRoot = null
    logsRoot = "${logsBase}${File.separator}${market.toUpperCase()}"
    switch( market.toLowerCase() ) {
      case "az":
        sourceRoot = configuration.modules.scan.forms.signin.sources.az
        break
      case "kc":
        sourceRoot = configuration.modules.scan.forms.signin.sources.kc
        break
      case "test":
        sourceRoot = configuration.modules.scan.forms.signin.sources.test
        break
    }
  }

  // PROCESS IMAGES
  //   1.  Copy all images from the source root to the input root.
  //   2.  Scan images to CSV file in output root.
  //   3.  Move images from input root to output root.
  public void processImages() {
    new File(sourceRoot).listFiles().toList().each() { afile ->
      try {
        // delete files from processing directory
        ant.delete() { 
         fileset( dir:inputRoot ) { include( name:"*" ) }
         fileset( dir:outputRoot ) { include( name:"*" ) }
        }
        // move files for processing
        ant.move( todir:inputRoot ) { 
         fileset( dir:sourceRoot ) { include( name:afile.getName() ) }
        }
        // rotate images 90 degrees
        def convert = new ImageMagick()
        new File(inputRoot).eachFileMatch(~/.*\.tif/) { file ->
         println "rotating file:  ${file}"
         convert.rotate(file, file, 90)
        } 
        // process images
        def firstFile = new File(inputRoot).listFiles().toList()[0]
        if( null != firstFile ) {
          def scanStation = new GravicScanStation()
          scanStation.process(referenceFile, firstFile, outputFile, logsRoot)
        }
        // move files after processing
        ant.move( todir:outputRoot ) { 
          fileset( dir:inputRoot ) { include( name:"*.tif" ) }
        }
        message = """<font color="blue">complete</font>"""
      } catch(e) {
        message =  """<font color="red">error</font>"""
        throw new Exception("Error processing images.", e)
      }
    }
  }

  // PROCESS IMAGES
  //   1.  Copy all images from the source root to the input root.
  //   2.  Scan images to CSV file in output root.
  //   3.  Move images from input root to output root.
  public void XprocessImages() {
    try {
      // delete files from processing directory
      ant.delete() { 
       fileset( dir:inputRoot ) { include( name:"*" ) }
       fileset( dir:outputRoot ) { include( name:"*" ) }
      }
      // move files for processing
      ant.move( todir:inputRoot ) { 
       fileset( dir:sourceRoot ) { include( name:"*.tif" ) }
      }
      // rotate images 90 degrees
      def convert = new ImageMagick()
      new File(inputRoot).eachFileMatch(~/.*\.tif/) { file ->
       println "rotating file:  ${file}"
       convert.rotate(file, file, 90)
      } 
      // process images
      def firstFile = new File(inputRoot).listFiles().toList()[0]
      if( null != firstFile ) {
        def scanStation = new GravicScanStation()
        scanStation.process(referenceFile, firstFile, outputFile, logsRoot)
      }
      // move files after processing
      ant.move( todir:outputRoot ) { 
        fileset( dir:inputRoot ) { include( name:"*.tif" ) }
      }
      message = """<font color="blue">complete</font>"""
    } catch(e) {
      message =  """<font color="red">error</font>"""
      throw new Exception("Error processing images.", e)
    }
  }


  // PARSE RESULTS
  public void parseResults() {
    try {
      //println "list file: ${outputFile}"
      if( (new File(outputFile)).exists() ) {
        def signinParser = new GravicSigninParser()
        def signinRecordset = signinParser.parseOutput(outputFile)
        signinParser.printRecordset(signinRecordset)
      }
      message = """<font color="blue">complete</font>"""
    } catch(e) {
      e.printStackTrace()
      message = """<font color="red">error</font>"""
      throw new Exception("Error parsing results.", e)
    }
  }

  // ARCHIVE FILES
  public void archiveFiles() {
    try {
      if( (new File(outputFile)).exists() ) {
        def fileMap = [:]
        def signinParser = new GravicSigninParser()
        def signinRecordset = signinParser.parseOutput(outputFile)
        def logFile = null
        def archive = new Archive(logsRoot, "Signin")
        signinRecordset.records.each() { record ->
          if( !fileMap.containsKey(record.formName) ) {
            fileMap.put( "${outputRoot}/${record.formName}", record )
          }
          logFile = archive.getLogFile("CP", record.classReportID, "LOG")
          logFile.append( record.getLogString() )
        }
        fileMap.each() { source, record ->
          archive.move(source, "CP", record.classReportID, "tif")
        }
      }
    } catch(e) {
      message = """<font color="red">archival failed</font>"""
      throw new Exception(e)
    }
  }

  // CALL WEBSERVICE
  // 1.  Upload results from CSV file in output root to database.
  // 2.  Move files from the output directory to the logs.
  // 3.  Call file archiver
  public void uploadResults() {
    try {
      if( (new File(outputFile)).exists() ) {
        def signinParser = new GravicSigninParser()
        def signinRecordset = signinParser.parseOutput(outputFile)
        def manager = new SessionManager(market)
        manager.setCredentials(username, password)
        def service = manager.getServiceClient()
        if(service.login()) {
          // logged in
        } else {
          message = """<font color="red">authorization failed</font>"""
          return
        }
        def url = null
        signinRecordset.records.each() { record ->
          url = record.getURL()
          //println "calling service: ${url}"
          def data = null
          try {
            data = service.webservice(url)
            //println "RESULT:  ${data}"
          } catch(e) {
            message = """<font color="red">webservice failed</font>"""
            //println e.getMessage()
            throw new Exception(e)
          }
        }
        message = """<font color="blue">complete</font>"""
      }
    } catch(e) {
        message = """<font color="red">webservice failed</font>"""
        //println e.getMessage()
        //message = e.getMessage()
        throw new Exception(e)
    }
  }

  // GET WEB RESPONSE
  public String getMessage() {
    return message
  }

}  // end of class


// *EOF*
